#![allow(unused)]

mod biz;
mod controller;
mod schedule;

use {
    axum::{
        routing::{get, post},
        Router,
    },
    repository::base,
    sqlx::{MySql, Pool},
    std::net::SocketAddr,
    tracing::{error, info},
};

pub async fn bootstrap(env: &'static str) -> anyhow::Result<()> {
    start_jobs(env).await?;

    start_server(env).await?;

    Ok(())
}

async fn start_server(env: &'static str) -> anyhow::Result<()> {
    let pool = base::db::pool(env).await?;
    let app_state = controller::common::AppState { env, pool };

    let router = Router::new()
        .route(
            "/generate_wallet",
            post(controller::wallet_controller::generate_wallet),
        )
        .route(
            "/coin/balance",
            get(controller::coin_controller::balance_coin),
        )
        .route(
            "/coin/transfer",
            post(controller::coin_controller::transfer_coin),
        )
        .route(
            "/token/balance",
            get(controller::token_controller::balance_token),
        )
        .route(
            "/token/transfer",
            post(controller::token_controller::transfer_token),
        )
        .with_state(app_state);

    let server_addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    let listener = tokio::net::TcpListener::bind(server_addr).await?;
    info!("listener -> {}:{}", server_addr.ip(), server_addr.port());
    axum::serve(listener, router).await?;

    Ok(())
}

async fn start_jobs(env: &'static str) -> anyhow::Result<()> {
    let pool_out = base::db::pool(env).await?;
    tokio::spawn(async move {
        let pool = pool_out;
        tokio::join!(
            schedule::tron_listen_token::job(env, &pool),
            schedule::tron_auto_transfer::recharge_job(env, &pool),
            schedule::tron_auto_transfer::collect_job(env, &pool),
        );
    });

    Ok(())
}
